﻿	float Tools::to_radian(float degree)
	{
		return (degree*3.1415926f / 180.0f);
	}
	float Tools::to_degree(float radian)
	{
		return (radian*180.0f / 3.1415926f);
	}
	void  Tools::to_xy(float angle, float &to_x, float &to_y)
	{
		if (angle < 90.0f) //0~90
		{
			to_x = cos(to_radian(angle));
			to_y = sin(to_radian(angle));
		}
		else if (angle < 180.0f)//90~180
		{
			to_x = -cos(to_radian(180.0f - angle));
			to_y = sin(to_radian(180.0f - angle));
		}
		else if (angle < 270.0f)//180~270
		{
			to_x = -cos(to_radian(angle - 180.0f));
			to_y = -sin(to_radian(angle - 180.0f));
		}
		else  //270~360                   
		{
			to_x = cos(to_radian(360.0f - angle));
			to_y = -sin(to_radian(360.0f - angle));
		}
	}
	float Tools::to_angle(const float &to_x, const float &to_y)
	{
		if (fabs(to_x) < 0.001f && fabs(to_y) < 0.001f) return 0.0f;
		float angle = 0.0f;
		float d = float(sqrt(to_x*to_x + to_y * to_y));
		float proto_angle = to_degree(asinf(fabs(to_y) / d));
		if (to_y >= 0.0f)
		{
			if (to_x >= 0.0f) angle = proto_angle;          //第一象限
			else              angle = 180.0f - proto_angle; //第二象限
		}
		else
		{
			if (to_x < 0.0f)  angle = 180.0f + proto_angle; //第三象限
			else              angle = 360.0f - proto_angle; //第四象限
		}
		return angle;
	}
	Point Tools::foot_point(const Point &pt, const Point &line_pt1, const Point &line_pt2)
	{
		auto &x0 = pt.X;
		auto &y0 = pt.Y;
		auto &x1 = line_pt1.X;
		auto &x2 = line_pt2.X;
		auto &y1 = line_pt1.Y;
		auto &y2 = line_pt2.Y;

		float dx = x2 - x1;
		float dy = y2 - y1;
		float u = (x0 - x1)*(x2 - x1) + (y0 - y1)*(y2 - y1);
		u /= (dx*dx + dy * dy);
		Point t;
		t.X = x1 + u * dx;
		t.Y = y1 + u * dy;
		return t;
	}
	bool  Tools::equal(const float &t1, const float &t2)
	{
		return fabs(t1 - t2) < 0.0001f;
	}
	Point Tools::cross_pt(const Point &pt1, const Point &pt2, const Point &pt3, const Point &pt4)
	{
		auto &X1 = pt1.X, &Y1 = pt1.Y;
		auto &X2 = pt2.X, &Y2 = pt2.Y;
		auto &X3 = pt3.X, &Y3 = pt3.Y;
		auto &X4 = pt4.X, &Y4 = pt4.Y;
		Point pt;
		if (equal(X1, X2))
		{
			if (!equal(X3, X4))
			{
				float k2 = (Y4 - Y3) / (X4 - X3);
				pt.X = X1;
				pt.Y = k2 * (X1 - X3) + Y3;
			}
		}
		else // !equal(X1, X2)
		{
			float k1 = (Y2 - Y1) / (X2 - X1);
			if (equal(X3, X4))
			{
				pt.X = X3;
				pt.Y = k1 * (X3 - X1) + Y1;
			}
			else
			{
				float k2 = (Y4 - Y3) / (X4 - X3);
				if (!equal(k1, k2))
				{
					pt.X = (Y3 - Y1 - k2 * X3 + X1 * k1) / (k1 - k2);
					pt.Y = k1 * (pt.X - X1) + Y1;
				}
			}
		}
		return pt;
	}
	bool Tools::too_near(const Point &pt1, const Point &pt2)
	{
		return (fabs(pt1.X - pt2.X) < 10.0f && fabs(pt1.Y - pt2.Y) < 10.0f);
	}
	bool angle_equal(const float &angle1, const float &angle2)
	{
		float d = fabs(angle1 - angle2);
		if (d < 0.01f || fabs(d - 360.0f) < 0.01f)
			return true;
		return false;
	}
	bool Tools::is_on_one_line(const Point &pt0, const Point &pt1, const Point &pt2, const Point &pt3)
	{
		float a1 = Tools::to_angle(pt1.X - pt0.X, pt1.Y - pt0.Y);
		float a2 = Tools::to_angle(pt2.X - pt1.X, pt2.Y - pt1.Y);
		float a3 = Tools::to_angle(pt3.X - pt2.X, pt3.Y - pt2.Y);
		if (angle_equal(a1, a2) && angle_equal(a2, a3))
			return true;
		return false;
	}